home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Music / MISC / mpegaudio / fixes.txt < prev    next >
Internet Message Format  |  1995-08-23  |  11KB

  1. From:    US1RMC::"seymour@m31.dgbt.doc.ca" "Seymour Shlien" 27-AUG-1993 15:05:31.82
  2. To:    3d::pan
  3. CC:    
  4. Subj:    problems and fixes
  5.  
  6. Dear Davis,
  7.  
  8. I have now got the MPEG audio coder and decoder to
  9. work on both UNIX (Sparc 2) and Microsoft C. All the problems
  10. that we encountered were mainly restricted to the code in the
  11. file common.c and were related to the AIFF
  12. audio format functions. I gather from the comments in
  13. the text, other people had encountered similar problems.
  14.  
  15. When compiled under UNIX,  the gcc compiler
  16. gave messages similar to below.  
  17.  
  18. common.c: In function `aiff_read_headers':
  19. common.c:673: warning: multi-character character constant
  20. common.c:674: warning: multi-character character constant
  21. common.c:688: warning: multi-character character constant
  22. common.c:719: warning: multi-character character constant
  23. common.c:719: warning: passing arg 2 of `strcmp' makes pointer from integer without a cast
  24. common.c: In function `aiff_write_headers':
  25. common.c:807: warning: multi-character character constant
  26. common.c:808: warning: multi-character character constant
  27. common.c:809: warning: multi-character character constant
  28.  
  29.    670     if (fread(&FormChunk, sizeof(Chunk), 1, file_ptr) != 1)
  30.    671        return(-1);
  31.    672   
  32.    673     if (*(unsigned long *) FormChunk.ckID != IFF_ID_FORM ||
  33.    674         *(unsigned long *) FormChunk.formType != IFF_ID_AIFF)
  34.    675        return(-1);
  35.    676
  36.    677
  37.    678  /*   if (strcmp(FormChunk.ckID,IFF_ID_FORM) ||
  38.    679         strcmp(FormChunk.formType,IFF_ID_AIFF))
  39.    680        return(-1);
  40.    681  */
  41.    ...
  42.    ...
  43.    715           aiff_ptr->numSampleFrames = CommChunk.numSampleFrames;
  44.    716           aiff_ptr->sampleSize = CommChunk.sampleSize;
  45.    717   
  46.    718  /*    } else if (*(unsigned long *)Header.ckID == IFF_ID_SSND) { */
  47.    719        } else if (strcmp(Header.ckID,IFF_ID_SSND)) {
  48.    720   
  49.    721           /*
  50.  
  51.  
  52. Similarly on MSDOS we obtained the following warnings
  53.  
  54. Microsoft (R) Program Maintenance Utility   Version 1.11    
  55. Copyright (c) Microsoft Corp 1988-90. All rights reserved.
  56.  
  57.     cl /AL /G2 /FPi87 /nologo /c /Gi musicin.c
  58. musicin.c
  59. musicin.c(959) : warning C4047: '!=' : different levels of indirection
  60.     cl /AL /G2 /FPi87 /nologo /c /Gi common.c
  61. common.c
  62. common.c(814) : warning C4047: '=' : different levels of indirection
  63. common.c(815) : warning C4047: '=' : different levels of indirection
  64. common.c(816) : warning C4047: '=' : different levels of indirection
  65.  
  66.    814   
  67.    815     *(unsigned long *) FormChunk.ckID     = IFF_ID_FORM;
  68.    816     *(unsigned long *) FormChunk.formType = IFF_ID_AIFF;
  69.    817     *(unsigned long *) CommChunk.ckID     = IFF_ID_COMM;
  70.    818
  71.    819     double_to_extended(&aiff_ptr->sampleRate, temp_sampleRate);
  72.   
  73. also a few similar error messages in musicin.c and musicout.c
  74.  
  75.  
  76. Despite these warnings both the encoder (musicin) and the decoder
  77. musicout appeared to run correctly on the data files 
  78. orig.mpg and sine.dec. However command line input is not
  79. properly implemented on MicroSoft C. The program tries to make
  80. a file orig.mpg.dec which is not legal in MSDOS
  81.  
  82.  
  83.  
  84.          BUGS  IN THE SOFTWARE
  85.  
  86. For MS_DOS it was necessary to modify the
  87. mem_alloc function in order to avoid crashing the computer on startup.
  88. I do not know the reason as I am not an expert in MicroSoft C.
  89.  
  90.  
  91. Also, the software does not properly handle AIFF formatted files.
  92. Using the program musicout I created an AIFF formatted file from
  93. the orig.mpg file. When I ran musicin on the AIFF formatted file on
  94. our SUN work station (ie UNIX environment) , the program crashed.
  95. On the other hand, when the same test was performed on the MSDOS,
  96. the computer did not crash but it failed to recognize the
  97. file as an AIFF formatted file and it did not read the header block.
  98. Nevertheless it was still able to compress the file, once the appropriate
  99. header information was typed in. 
  100.  
  101.  
  102. The problems seem to be related to the handling of the ID information
  103. in the chunk structure of the AIFF file. The ID is a 32 bit integer   
  104. which can take one of 5 designated values. The designated values
  105. for convenience also can be decoded as ascii strings FORM, AIFF
  106. COMM, SSND and MPEG. The ISO software attempts to provide two ways
  107. of handling these numbers- either as a multicharacter constant or
  108. a string.
  109.  
  110. In the common.h file
  111.  
  112. /*
  113.  * Note:  The value of a multi-character constant
  114.  *        is implementation-defined.
  115.  */
  116. #if !defined(MS_DOS) && !defined(AIX)
  117.  
  118. #define         IFF_ID_FORM             'FORM'
  119. #define         IFF_ID_AIFF             'AIFF'
  120. #define         IFF_ID_COMM             'COMM'
  121. #define         IFF_ID_SSND             'SSND'
  122. #define         IFF_ID_MPEG             'MPEG'
  123. #else
  124. #define         IFF_ID_FORM             "FORM"
  125. #define         IFF_ID_AIFF             "AIFF"
  126. #define         IFF_ID_COMM             "COMM"
  127. #define         IFF_ID_SSND             "SSND"
  128. #define         IFF_ID_MPEG             "MPEG"
  129. #endif
  130.  
  131.  
  132.  
  133. Unfortunately, the revisions to the code in common.c
  134. do not properly read or write the AIFF header block in
  135. either mode.
  136.  
  137. If the IFF_* constants are defined as a long integer, (ie
  138. single quotes around FORM, AIFF, etc.), then the strcmp
  139. function will crash on some machines because the inputs
  140. Header.ckID and IFF_ID_FORM are not strings. Strcmp
  141. expects to receive null terminated strings. Since it
  142. instead receives addresses to nonterminated strings, the
  143. strcmp runs off to infinity searching for the null character.
  144.  
  145. Note: when IFF_* are defined as strings, Header.ckID is
  146. still not a null terminated string. Fortunately strcmp
  147. stops when a null is encountered in either one of its 
  148. arguments -- in this case a null is encountered in
  149. IFF_*. It might be safer to use strncmp which includes
  150. a string length argument.
  151.  
  152.   
  153.  
  154. This was the source of our problem on the UNIX machine as
  155. the common.c attempted to do a string compare in one
  156. spot (around line 718). 
  157.  
  158. /*    } else if (*(unsigned long *)Header.ckID == IFF_ID_SSND) { */
  159.       } else if (strcmp(Header.ckID,IFF_ID_SSND)) {
  160.  
  161. The commented line would have worked correctly in the
  162. UNIX environment.
  163.  
  164.  
  165. A different problem occurs in MS_DOS. In the function 
  166. aiff_write_header the following statement does not do what
  167. was intended when IFF_ID_FORM is a string.
  168.  
  169.   *(unsigned long *) FormChunk.ckID     = IFF_ID_FORM;
  170.  
  171. IFF_ID_FORM points to an address of the string "FORM". Though
  172. it was intended to put "FORM" in FormChunk.ckID, the above
  173. statement instead places the address of IFF_ID_FORM into
  174. FormChunk.ckID. This is what is put in the AIFF file. Musicin
  175. reads the file and fails to recognize it as an AIFF file. (The
  176. above statement would have been correct if IFF_ID_FORM was
  177. a long integer.) 
  178.  
  179.  
  180.                FIXES
  181.  
  182. I have made the following changes in the software so that it
  183. can now handle AIFF formatted files in either MicroSoft C or
  184. UNIX.
  185.  
  186. In common.h, I have introduced a new def called IFF_LONG
  187. whenever IFF_* is represented by multicharacter longs instead
  188. of strings. 
  189.  
  190. 187,188c187
  191. < #if !defined(MS_DOS) && !defined(AIX)  
  192. < #define         IFF_LONG
  193. ---
  194. > #if !defined(MS_DOS) && !defined(AIX)
  195.  
  196.  
  197.  
  198.  
  199. In common.c the following changes were made
  200.  
  201.  
  202. For avoiding crashing the PC on startup
  203. 456,457c456
  204. <     /*ptr = (void FAR *) _fmalloc((unsigned int)block);*/ /* far memory, 92-07-08 sr */
  205. <     ptr = (void FAR *) malloc((unsigned int)block); /* far memory, 93-08-24 ss */
  206. ---
  207. >     ptr = (void FAR *) _fmalloc((unsigned int)block); /* far memory, 92-07-08 sr */
  208.  
  209.  
  210.  
  211. For debugging and testing
  212. 646,656d644
  213. < /****  for debugging 
  214. < showchar(str)
  215. < char str[4];
  216. < {
  217. < int i;
  218. < for (i=0;i<4;i++) printf("%c",str[i]);
  219. < printf("\n");
  220. < }
  221. < ****/
  222.  
  223.  
  224. To correct the problems with the IFF_* ID's I do
  225. the string comparisons two different ways depending
  226. on whether IFF_LONG is defined. 
  227.  
  228.  
  229.  
  230. 685d672
  231. < #ifdef IFF_LONG 
  232. 689d675
  233. < #else
  234. 691,694d676
  235. <    if (strncmp(FormChunk.ckID,IFF_ID_FORM,4) ||
  236. <        strncmp(FormChunk.formType,IFF_ID_AIFF,4))
  237. <       return(-1);
  238. < #endif
  239. 695a678,681
  240. > /*   if (strcmp(FormChunk.ckID,IFF_ID_FORM) ||
  241. >        strcmp(FormChunk.formType,IFF_ID_AIFF))
  242. >       return(-1);
  243. > */
  244. 702d687
  245. < #ifdef IFF_LONG  
  246. 705,708c690,691
  247. < #else
  248. <       if (strncmp(Header.ckID,IFF_ID_COMM,4) == 0) {
  249. < #endif
  250. ---
  251. > /*      if (strcmp(Header.ckID,IFF_ID_COMM)) {
  252. > */
  253. 711a695
  254. 734,738c718,720
  255. < #ifdef IFF_LONG 
  256. <       } else if (*(unsigned long *)Header.ckID == IFF_ID_SSND) { 
  257. < #else
  258. <       } else if (strncmp(Header.ckID,IFF_ID_SSND,4) == 0) {
  259. < #endif
  260. ---
  261. > /*    } else if (*(unsigned long *)Header.ckID == IFF_ID_SSND) { */
  262. >       } else if (strcmp(Header.ckID,IFF_ID_SSND)) {
  263. 741a724
  264. 824d806
  265. < #ifdef IFF_LONG 
  266. 828,832d809
  267. < #else
  268. <    strncpy(FormChunk.ckID,IFF_ID_FORM,4);
  269. <    strncpy(FormChunk.formType,IFF_ID_AIFF,4);
  270. <    strncpy(CommChunk.ckID,IFF_ID_COMM,4);
  271. < #endif
  272. 1536a1514
  273.  
  274.  
  275.  
  276.  
  277. In musicin.c
  278.  
  279. The following changes were made for the same reasons discussed above.
  280.  
  281.  
  282. 959d958
  283. < #ifdef IFF_LONG
  284. 961,963d959
  285. < #else
  286. <     if (strncmp(&pcm_aiff_data->sampleType,IFF_ID_SSND,4)) {
  287. < #endif
  288.  
  289.  
  290.  
  291. In musicout.c
  292.  
  293. The following changes were made for the same reasons discussed above.
  294.  
  295.  
  296. 381d380
  297. < #ifdef IFF_LONG       
  298. 383,385d381
  299. < #else
  300. <        strncpy(&pcm_aiff_data.sampleType,IFF_ID_SSND,4);
  301. < #endif
  302. 388c384
  303. <  
  304. ---
  305.  
  306.  
  307. This is a copy of the makefile that I am using on the IBM. Perhaps
  308. one of the switches might explain why I had trouble with the 
  309. mem_alloc.
  310.  
  311. ALL : musicin.exe musicout.exe
  312.  
  313. CFLAGS = /AL /G2 /FPi87 /nologo /c /Gi /F 256 
  314. LFLAGS= /SE:256 /ST:16000 /F /PACKC
  315.  
  316. musicin.obj: musicin.c common.h encoder.h
  317.     cl $(CFLAGS) musicin.c
  318.  
  319. common.obj: common.c common.h
  320.     cl $(CFLAGS) common.c
  321.  
  322. encode.obj: encode.c common.h encoder.h
  323.     cl $(CFLAGS) encode.c
  324.  
  325. subs.obj: subs.c common.h encoder.h
  326.     cl $(CFLAGS) subs.c
  327.  
  328. psy.obj: psy.c common.h encoder.h
  329.     cl $(CFLAGS) psy.c
  330.  
  331. tonal.obj: tonal.c common.h encoder.h
  332.     cl $(CFLAGS) tonal.c
  333.  
  334. musicout.obj: musicout.c common.h decoder.h
  335.     cl $(CFLAGS) musicout.c
  336.  
  337. decode.obj: decode.c common.h decoder.h
  338.     cl $(CFLAGS) decode.c
  339.  
  340. musicin.exe: musicin.obj common.obj encode.obj subs.obj psy.obj tonal.obj
  341.     link $(LFLAGS) musicin common encode subs psy tonal,musicin,,;
  342.  
  343. musicout.exe: musicout.obj common.obj decode.obj subs.obj
  344.     link $(LFLAGS) musicout common decode subs,musicout,,;
  345.  
  346.  
  347.  
  348.  
  349. I am grateful, for the help from Daniel Lauzon -- our resident C and C++
  350. expert. Also Bill Truerniet helped me with Microsoft C 
  351. on the PC.
  352.    
  353.  
  354. seymour@dgbt.doc.ca
  355.  
  356.  
  357. % ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ======
  358. % Received: by us1rmc.bb.dec.com; id AA06920; Fri, 27 Aug 93 14:58:09 -0400
  359. % Received: by inet-gw-1.pa.dec.com; id AA02547; Fri, 27 Aug 93 11:59:18 -0700
  360. % Received: from rigel.dgbt.doc.ca by  m31.dgbt.doc.ca (4.1/SMI-4.1) id AA01692; Fri, 27 Aug 93 14:57:59 ED
  361. % Date: Fri, 27 Aug 93 14:57:59 EDT
  362. % From: seymour@m31.dgbt.doc.ca (Seymour Shlien)
  363. % Message-Id: <9308271857.AA01692@ m31.dgbt.doc.ca>
  364. % To: 3d::pan
  365. % Subject: problems and fixes
  366.